<?php (defined('BASEPATH')) OR exit('No direct script access allowed');

/* define the modules base path */
define('MODBASE', dirname(FCPATH).'/modules/');

/* define the offset from application/controllers */
define('MODOFFSET', '../../modules/');

/**
 * Modular Extensions - PHP5
 *
 * Adapted from the CodeIgniter Core Classes
 * @copyright	Copyright (c) 2006, EllisLab, Inc.
 * @link		http://codeigniter.com
 *
 * Description:
 * This library extends the CodeIgniter router class.
 *
 * Install this file as application/libraries/MY_Router.php
 *
 * @copyright 	Copyright (c) Wiredesignz 2008-11-20
 * @version 	5.1.40
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 **/
class MY_Router extends CI_Router
{
    public function  __construct() {
        
        $this->config =& load_class('Config');
        $this->uri =& load_class('URI');
        log_message('debug', "Router Class Initialized");
        
        if ($this->config->item('router', 'core_main') === false) {
            
            $this->config->set_core('router', $this->_get_tree());
        }
        
        $tree = $this->config->item('router', 'core_main');
        
        $this->_set_routing($tree);        
        $this->uri->initialize_modul_segments($this->_find_current($tree));
    }
    
    
	public function _validate_request($segments)
	{
		(isset($segments[1])) OR $segments[1] = NULL;
	
		/* locate the module controller */
		list($module, $controller) = Router::locate($segments);

		/* no controller found */
		($module === FALSE) AND show_404($controller);
		
		/* set the module directory */
		Router::$path = ($controller) ? $module : NULL ;
		
		/* set the module path */
		$path = ($controller) ? MODOFFSET.$module.'/controllers/' : NULL;

		$this->set_directory($path);

		/* remove the directory segment */
		if ($controller != $module AND $controller != NULL)
			$segments = array_slice($segments, 1);

		return $segments;
	}
	
	
    public function _set_routing($tree)
    {
        // Are query strings enabled in the config file?
        // If so, we're done since segment based URIs are not used with query strings.
        if ($this->config->item('enable_query_strings') === TRUE AND isset($_GET[$this->config->item('controller_trigger')]))
        {
            $this->set_class(trim($this->uri->_filter_uri($_GET[$this->config->item('controller_trigger')])));

            if (isset($_GET[$this->config->item('function_trigger')]))
            {
                $this->set_method(trim($this->uri->_filter_uri($_GET[$this->config->item('function_trigger')])));
            }
            
            return;
        }
        
        // Load the routes.php file.
        //@include(APPPATH.'config/routes'.EXT);
        //$this->routes = ( ! isset($route) OR ! is_array($route)) ? array() : $route;
        //unset($route);

        $this->default_controller = $tree['www']['modul'].'/'.$tree['www']['method'];
        $this->routes['scaffolding_trigger'] = '';
        $this->routes['ajax/(:any)'] = "$1";
        
        foreach($tree as $uri => $row) {
            
            if ($uri == 'www') { continue;}
            
            $mask = ''; $parametrs = '';
            
            if ($row['mask'] != NULL) {
                
                $mask = '/'.$row['mask'];
            }
            
            if ($row['parametrs'] != NULL) {
                
                $parametrs = '/'.$row['parametrs'];
            }
            
            $this->routes[$row['url'].$mask] = $row['modul'].'/'.$row['method'].$parametrs;
            $this->routes['ajax/'.$row['url'].$mask] = $row['modul'].'/'.$row['method'].$parametrs;
        }
        //print '<pre>';
        //print_r($this->routes);
        // Set the default controller so we can display it in the event
        // the URI doesn't correlated to a valid controller.
        //$this->default_controller = ( ! isset($this->routes['default_controller']) OR $this->routes['default_controller'] == '') ? FALSE : strtolower($this->routes['default_controller']);   
        
        // Fetch the complete URI string
        $this->uri->_fetch_uri_string();
    
        // Is there a URI string? If not, the default controller specified in the "routes" file will be shown.
        if ($this->uri->uri_string == '')
        {
            if ($this->default_controller === FALSE)
            {
                show_error("Unable to determine what should be displayed. A default route has not been specified in the routing file.");
            }

            // Turn the default route into an array.  We explode it in the event that
            // the controller is located in a subfolder
            $segments = $this->_validate_request(explode('/', $this->default_controller));

            // Set the class and method
            $this->set_class($segments[0]);
            $this->set_method('index');
            
            // Assign the segments to the URI class
            $this->uri->rsegments = $segments;
            
            // re-index the routed segments array so it starts with 1 rather than 0
            $this->uri->_reindex_segments();
            
            log_message('debug', "No URI present. Default controller set.");
            return;
        }
        unset($this->routes['default_controller']);
        
        // Do we need to remove the URL suffix?
        $this->uri->_remove_url_suffix();
        
        // Compile the segments into an array
        $this->uri->_explode_segments();
        
        // Parse any custom routing that may exist
        $this->_parse_routes();     
        
        // Re-index the segment array so that it starts with 1 rather than 0
        $this->uri->_reindex_segments();
    }
    
	
    private function _find_current($tree) {
        
        $return = 'www';
        
        if ($this->uri->total_segments() == 0) {
            
            return $return;
        }
        
        foreach ($this->uri->segment_array() as $row) {
            
            if ($row == 'ajax') { continue;}
            
            if (isset($tree[$row])) {
                
                $return = $row;
            }
            else {
                
                return $return;
            }
        }
        
        return $return;
    }
    
    
    private function _get_tree() {
        
        //Загружаем класс для работы с базой данных
        require_once(BASEPATH.'database/DB'.EXT);
        
        $DB = DB();
        $array = array();
        $query = $DB->get('pages');
        
        foreach ($query->result_array() as $row) {
            
            $array[$row['parent_id']][] = $row;
        }
        
        return $this->_tree($array[0], $array);
    }
    
    
    private function _tree($main, $array, $level = 0, $url = array()) {
        
        foreach($main as $row) {
            
            if ($row['uri'] != 'www') {
                
                $url[$level] = $row['uri'];
            }
            
            $return[$row['uri']] = $row;
            $return[$row['uri']]['level'] = $level;
            $return[$row['uri']]['url'] = implode('/', $url);
            
            if (isset($array[$row['id']])) {
                
                $return = $return + $this->_tree($array[$row['id']], $array, $level+1, $url);
            }
        }
        
        return $return;
    }
    
}

class Router
{
	public static $path;
	
	/** Locate the controller **/
	public static function locate($segments)
	{		
		list($module, $controller) = $segments;
		
		/* a module? */
		if ($module AND is_dir(MODBASE.$module))
		{
			($controller == NULL) AND $controller = $module;
			
			/* a module sub-controller? */
			if(is_file(MODBASE.$module.'/controllers/'.$controller.EXT))			
				return array($module, $controller);
				
			/* a module controller? */
			return array($module, $module);
		}
		
		/* an application controller? */
		if (is_file(APPPATH.'controllers/'.$module.EXT))
			return array($module, NULL);
		
		/* no controller found */
		return array(FALSE, NULL);
	}
}